from django.test import TestCase
from lists.views import home_page
from django.urls import resolve
from django.http.request import HttpRequest
from django.template.loader import render_to_string
from lists.models import Item, List


# Create your tests here.


class SmokeTest(TestCase):
    def test_bad_math(self):
        self.assertEqual(1 + 2, 3)


class HomePageTest(TestCase):
    def test_root_url_resolves_to_home_page_view(self):
        found = resolve("/")
        self.assertEqual(found.func, home_page)

    def test_home_page_returns_correct_html(self):
        response = self.client.get("/")
        html = response.content.decode("utf8")
        self.assertTrue(html.startswith("<!DOCTYPE html>"))
        self.assertTemplateUsed(response, "lists/home.html")
        self.assertTrue(html.endswith("</html>"))

    def test_uses_home_template(self):
        response = self.client.get("/")
        self.assertTemplateUsed(response, "lists/home.html")

    def test_only_saves_items_when_necessary(self):
        self.client.get("/")
        self.assertEqual(Item.objects.count(), 0)


class ListViewTest(TestCase):
    def test_display_all_items(self):
        list_ = List.objects.create()
        Item.objects.create(text="itemey 1", list=list_)
        Item.objects.create(text="itemey 2", list=list_)
        res = self.client.get(f"/lists/{list_.id}/")
        self.assertContains(res, "itemey 1")
        self.assertContains(res, "itemey 2")

    # def test_uses_list_template(self):
    #     res = self.client.get("/lists/1/")
    #     self.assertTemplateUsed(res, "lists/list.html")

    def test_displays_only_items_for_that_list(self):
        correct_list = List.objects.create()
        Item.objects.create(text="itemey 1", list=correct_list)
        Item.objects.create(text="itemey 2", list=correct_list)
        other_list = List.objects.create()
        Item.objects.create(text="other list item 1", list=other_list)
        Item.objects.create(text="other list item 2", list=other_list)
        res = self.client.get(f"/lists/{correct_list.id}/")
        self.assertContains(res, "itemey 1")
        self.assertContains(res, "itemey 2")
        self.assertNotContains(res, "other list item 1")
        self.assertNotContains(res, "other list item 2")

    def test_pass_correct_list_to_template(self):
        other_list = List.objects.create()
        correct_list = List.objects.create()
        response = self.client.get(f'/lists/{correct_list.id}/')
        self.assertEqual(response.context['list'], correct_list)


class NewListTest(TestCase):
    def test_can_save_post_request(self):
        res = self.client.post("/lists/new", data={"item_text": "A new list item"})
        self.assertEqual(Item.objects.count(), 1)
        new_item = Item.objects.first()
        self.assertEqual(new_item.text, "A new list item")

    def test_redirects_after_post(self):
        res = self.client.post("/lists/new", data={"item_text": "A new list item"})
        list = List.objects.first()
        self.assertRedirects(res, f"/lists/{list.id}/")

    def test_can_save_a_post_request_to_an_existing_list(self):
        other_list = List.objects.create()
        correct_list = List.objects.create()
        self.client.post(f'/lists/{correct_list.id}/add_item', data={'item_text': 'A new item for a existing list'})
        self.assertEqual(Item.objects.count(), 1)
        new_item = Item.objects.first()
        self.assertEqual(new_item.list, correct_list)

    def test_redirects_to_list_view(self):
        other_list = List.objects.create()
        correct_list = List.objects.create()
        res = self.client.post(f'/lists/{correct_list.id}/add_item',
                               data={'item_text': 'A new item for a existing list'})
        self.assertRedirects(res, f'/lists/{correct_list.id}/')


class ListAndItemModelTest(TestCase):
    def test_saving_and_retriving_items(self):
        list_ = List()
        list_.save()

        first_item = Item()
        first_item.text = "The first (ever) list item"
        first_item.list = list_
        first_item.save()
        saved_list = List.objects.first()
        self.assertEqual(saved_list, list_)
        second_item = Item()
        second_item.text = "Item the second"
        second_item.list = list_
        second_item.save()
        saved_items = Item.objects.all()
        self.assertEqual(saved_items.count(), 2)
        first_saved_item = saved_items[0]
        second_saved_item = saved_items[1]
        self.assertEqual(first_saved_item.text, "The first (ever) list item")
        self.assertEqual(first_saved_item, first_item)
        self.assertEqual(second_saved_item.text, "Item the second")
        self.assertEqual(second_saved_item, second_item)
